class Dep {
  constructor() {
    this.subscribers = new Set()  //集合 内容不会重复
  }

  depend() {
    if (activeEffect) {
      this.subscribers.add(activeEffect)
    }
  }

  notify() {
    this.subscribers.forEach(effect => {
      effect()
    })
  }
}
// const dep = new Dep()

let activeEffect = null
function watchEffect(effect) {
  activeEffect = effect
  // dep.depend()
  effect()
  activeEffect = null
}

// Map({key: value}): key是一个字符串
// WeakMap({key(对象): value}): key是一个对象 弱引用
const targetMap = new WeakMap()
function getDep(target, key) {
  //1.根据对象target 取出对应的Map对象 没有就创建
  let depsMap = targetMap.get(target)
  if (!depsMap) {
    depsMap = new Map()
    targetMap.set(target, depsMap)
  }
  //2.取出具体的dep对象
  let dep = depsMap.get(key)
  if (!dep) {
    dep = new Dep()
    depsMap.set(key, dep)
  }

  return dep
}

// vue3对raw进行数据劫持
function reactive(raw) {
  return new Proxy(raw, {
    get(target, key) {
      const dep = getDep(target, key)
      dep.depend()
      return target[key]
    },
    set(target, key, newVal) {
      if (target[key] !== newVal) {
        const dep = getDep(target, key)
        target[key] = newVal
        dep.notify()
      }
    }
  })
}


const info = reactive({ counter: 100, name: "yzh" })
const foo = reactive({ height: 1.88 })

watchEffect(function() {
  console.log(info.counter * 2, info.name);
})
watchEffect(function() {
  console.log(info.counter * info.counter);
})
watchEffect(function() {
  console.log(info.counter + 10, info.name);
})
watchEffect(function() {
  console.log(foo.height);
})

info.counter++;
// info.name = "yzh"


